define(['knockout', 'registerCommon', 'config', 'knockout-mapping'], function (ko, RegisterCommon, Config) {
    ko.options.deferUpdates = true;
    RegisterCommon.registerCmp();

    function ViewModel(params) {
        $.extend(this, {
            mobile: false,
            menus: [],
            mainCol2Css: Config.mainCol2Css,
            buttonCss: Config.buttonCss,
            storeCache: {}
        });
        $.extend(this, params);

        var scope = this;

        if (!scope.fluid) {
            scope.fluid = scope.mobile;
        }

        scope.fluidCss = {};
        scope.fluidCss['container' + (scope.fluid ? '-fluid' : '')] = true;

        ['topCmp', 'mainCmp', 'bottomCmp'].forEach(function (item) {
            if (scope[item]) {//the field is config in app
                if (scope[item] instanceof Object) {
                    scope[item] = {name: ko.observable(scope[item].name), params: ko.observable(scope[item].params)};
                } else {
                    scope[item] = ko.mapping.fromJS({name: scope[item], params: undefined})
                }
            } else {
                if (item == 'mainCmp') {
                    scope[item] = ko.mapping.fromJS(Config.koTemplate.emptyCmp);
                } else {
                    scope[item] = ko.observable();
                }
            }
        });

        for (var rl = 2; rl <= Config.route.maxLevel; ++rl) {
            scope['{0}Cmp'.formatTpl(Config.route.order[rl])] = ko.mapping.fromJS(Config.koTemplate.emptyCmp);
        }
        //main cmp contain second cmp
        //scope.secondCmp = ko.observable({name: 'cmp:Empty', params: undefined});
        //second cmp contain third cmp
        //scope.thirdCmp = ko.observable({name: 'cmp:Empty', params: undefined});
        //third cmp contain fourth cmp
        //scope.fourthCmp = ko.observable({name: 'cmp:Empty' ,params: undefined});
        // scope.router = Router().configure({
        //     notfound: function () {
        //         var maxLevel = Util.getHashMaxLevel();
        //
        //         if (maxLevel > 0) {
        //             var cmpL1 = Util.getCmpFromHash(1);
        //
        //             //console.log(ko.root.mainCmp(),cmpL1);
        //             //console.log(Util.jsEqual(ko.root.mainCmp(),cmpL1));
        //
        //             //if (!ko.root.mainCmp() || ko.root.mainCmp().name != cmpL1.name) {
        //             if(!Util.jsEqual(ko.root.mainCmp(),cmpL1)||maxLevel == 1){
        //                 console.log(ko.root.mainCmp(),cmpL1);
        //                 ko.root.mainCmp(cmpL1);
        //                 ko.root.secondCmp({name: 'cmp:Empty',params:{}});
        //             }
        //
        //         }
        //
        //         if (maxLevel > 1) {
        //             var cmpL2 = Util.getCmpFromHash(2);
        //             //console.log(ko.root.secondCmp(),cmpL2);
        //             //console.log(Util.jsEqual(ko.root.secondCmp(),cmpL2));
        //             //if (!ko.root.secondCmp() || ko.root.secondCmp().name != cmpL2.name)
        //             if(!Util.jsEqual(ko.root.secondCmp(),cmpL2)){
        //                 console.log(ko.root.secondCmp(),cmpL2);
        //                 ko.root.secondCmp(cmpL2);
        //             }
        //         }
        //     }
        // });

        scope.showProgress = ko.observable(false);
        scope.modalStack = ko.observableArray();
        scope.openModal = function (modalConfig) {
            var params = {};
            var cmp = 'cmp:Modal';

            if (modalConfig) {
                if (modalConfig.name) {
                    cmp = modalConfig.name;
                    params = modalConfig.params;
                } else {
                    params = modalConfig;
                }
            } else {
                params = {record: {bodyCmp: 'cmp:Empty'}};
            }

            params['_id'] = 'modal_' + scope.modalStack().length;
            scope.modalStack.push({cmp: cmp, params: params});
        }

        scope.hideModal = function () {
            scope.modalStack.pop();
        }

        //show modal with layui layer
        scope.openIFrameLayer = function (layerConfig) {
            layer.open($.extend({type: 2}, layerConfig));
        };

        //show a ko component in layui layer content
        scope.openPageLayer = function (/*{layerConfig:,modalConfig:}*/ data) {
            data.modalConfig.params.onReady = function () {
                scope.openLayer($.extend({
                    //type: 1,
                    zIndex: 100,
                    content: $('#modal_{0}'.formatTpl(scope.modalStack().length - 1)),
                    end: function () {
                        scope.hideModal()
                    }
                }, data.layerConfig));
            };

            scope.openModal(data.modalConfig);
        };
        //open a common layui layer
        scope.openLayer = function (layerConfig) {
            layer.open($.extend({
                type: 1,
                content: '',
                area: ['100%', '100%']
            },layerConfig));
        };
        //show a layui layer loading
        scope.showLoading = function () {
            layer.load(1, {
                shade: [0.05, '#000'] //0.1透明度的白色背景
            });
        };
        scope.closeLoading = function () {
            layer.closeAll('loading')
        };

        ko.computed(function () {
            scope.mainCmp.name();
            scope.storeCache = {};//cache the store which has the id
        });
    }

    return ViewModel;
});
